﻿using Microsoft.AspNetCore.Http;
using System;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TestEFAbstractEntity;
using Microsoft.Extensions.DependencyInjection;
using TestEFAbstractEntity.Entities;

namespace TestEFAbstractEntity1
{
    public class ToDoSomething
    {
        HttpContext _context;
        Repository repository;
        public ToDoSomething (HttpContext httpContext)
        {
            _context = httpContext;

            repository = _context.RequestServices.GetService<Repository>();
        }

        public async Task AddDataAsync()
        {
            await LogTitleAsync("添加数据");

            var sn1 = new SimpleWorkNode
            {
                Id = Guid.NewGuid(),
                ApprovalUser = "admin1",
                Name = "简单节点1",
            };
            var wnEvent = new WorkNodeEvent {
                Id = Guid.NewGuid(),
                OtherMessage ="testEvent",
                WorkNode=sn1,
            };
            var sn2 = new SimpleWorkNode
            {
                Id = Guid.NewGuid(),
                ApprovalUser = "admin2",
                Name = "简单节点2",
            };
            var sn3 = new SimpleWorkNode
            {
                Id = Guid.NewGuid(),
                ApprovalUser = "admin3",
                Name = "简单节点3",
            };
            var sn4 = new SimpleWorkNode
            {
                Id = Guid.NewGuid(),
                ApprovalUser = "admin4",
                Name = "简单节点4",
            };
            var sn5 = new SimpleWorkNode
            {
                Id = Guid.NewGuid(),
                ApprovalUser = "admin5",
                Name = "简单节点5",
            };
            var sn6 = new SimpleWorkNode
            {
                Id = Guid.NewGuid(),
                ApprovalUser = "admin6",
                Name = "简单节点6",
            };
            var sn7 = new SimpleWorkNode
            {
                Id = Guid.NewGuid(),
                ApprovalUser = "admin7",
                Name = "简单节点7",
            };

            var sn4_1= new SimpleWorkNode
            {
                Id = Guid.NewGuid(),
                ApprovalUser = "admin4-1",
                Name = "简单节点4-1",
            };
            var sn4_2 = new SimpleWorkNode
            {
                Id = Guid.NewGuid(),
                ApprovalUser = "admin4-2",
                Name = "简单节点4-2",
            };

            //sn1.NextNode = sn2;
            //sn2.NextNode = sn3;
            //sn3.NextNode = sn4;

            sn4.NextNode = sn4_1;
            sn4_1.NextNode = sn4_2;


            var cn1 = new CountersignNode
            {
                Id = Guid.NewGuid(),
                Name = "会签节点1",
            };

            var cn2 = new CountersignNode
            {
                Id = Guid.NewGuid(),
                Name = "会签节点2",
            };

            var pn1 = new ParalleNode
            {
                Id = Guid.NewGuid(),
                Name = "并行节点1",
            };
            var pn2 = new ParalleNode
            {
                Id = Guid.NewGuid(),
                Name = "并行节点2",
            };

            sn1.NextNode = cn1;

            cn1.ChildNodes.Add(pn1);
            cn1.ChildNodes.Add(sn2);

            pn1.ChildNodes.Add(sn3);
            pn1.ChildNodes.Add(cn2);

            cn2.ChildNodes.Add(sn4);
            cn2.ChildNodes.Add(sn5);

            cn1.NextNode = pn2;
            pn2.ChildNodes.Add(sn6);
            pn2.ChildNodes.Add(sn7);

            //repository.SimpleWorkNodes.Add(sn1);
            repository.WorkNodeEvents.Add(wnEvent);
            
            //repository.SimpleWorkNodes.Add(sn2);
            //repository.SimpleWorkNodes.Add(sn3);
            //repository.SimpleWorkNodes.Add(sn4);
            //repository.SimpleWorkNodes.Add(sn5);
            //repository.SimpleWorkNodes.Add(sn6);
            //repository.SimpleWorkNodes.Add(sn7);

            //repository.CountersignNodes.Add(cn1);
            //repository.CountersignNodes.Add(cn2);

            //repository.ParalleNodes.Add(pn1);
            //repository.ParalleNodes.Add(pn2);

            repository.SaveChanges();

            await LogTitleAsync("数据添加完成");
        }

        public async Task RemoveDataAsync()
        {
            await LogTitleAsync("删除数据");

            repository.SimpleWorkNodes.RemoveRange(repository.SimpleWorkNodes.ToArray());
            repository.CountersignNodes.RemoveRange(repository.CountersignNodes.ToArray());
            repository.ParalleNodes.RemoveRange(repository.ParalleNodes.ToArray());
            repository.WorkNodeEvents.RemoveRange(repository.WorkNodeEvents.ToArray());
            repository.SaveChanges();
            await LogTitleAsync("数据删除完成");
        }

        public async Task UpdateDataAsync()
        {
            await LogTitleAsync("开始更新数据");

            await LogTitleAsync("数据更新完成");
        }

        public async Task ApprovalAsync()
        {
            await LogTitleAsync("开始审批");
            var sn1 = repository.SimpleWorkNodes.FirstOrDefault(p => p.Name.Equals("简单节点1"));
            var workEvent = repository.WorkNodeEvents.FirstOrDefault(p => p.WorkNode.Id.Equals(sn1.Id));
            workEvent?.InitEvent();
            sn1.Approval();
            await LogContentAsync($"sn1.Equals(workEvent.WorkNode)：{sn1.Equals(workEvent.WorkNode)}");
            await LogContentAsync(sn1.Message.ToString());
            await LogContentAsync($"OtherMessage：{workEvent.OtherMessage}");
            await LogTitleAsync("审批完成");

            repository.SaveChanges();
        }

        public async Task RejectAsync()
        {
            await LogTitleAsync("开始审批");
            var sn1 = repository.SimpleWorkNodes.FirstOrDefault(p => p.Name.Equals("简单节点1"));
            var workEvent = repository.WorkNodeEvents.FirstOrDefault(p => p.Id.Equals(sn1.Id));
            workEvent?.InitEvent();
            sn1.Reject();
            await LogAsync(sn1.Message.ToString());
            await LogAsync($"OtherMessage：{workEvent.OtherMessage}");
            await LogTitleAsync("审批完成");
            repository.SaveChanges();
        }

        public async Task LogDataAsync()
        {
            var sbHtml = new StringBuilder();

            sbHtml.Append("<html>");
            sbHtml.Append("<head>");
            sbHtml.Append("<title>工作节点预览</title>");
            sbHtml.Append("<style type=\"text/css\">");

            sbHtml.Append(@".nodeView {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;    
    align-content: center;
    justify-content: flex-start;
    align-items: center;
}");
            sbHtml.Append(@".title {
    font-size: 12;
  /**  font-weight: bold; **/
    background-color: #031425;
    text-align: center;
    color: white;
    border-radius: 10px;
    padding: 10px;
}");
            sbHtml.Append(@".node-next{    
    color: #ff0000;
    font-weight: bold;
    font-size: 16px;
}");
            sbHtml.Append(@".simple-work-node-title {
    background-color: #03284c;
}");
            sbHtml.Append(@".countersign-work-node-title {
    background-color: #033261;
}");
            sbHtml.Append(@".paralle-work-node-title {
    background-color: #264c73;
}");
            sbHtml.Append(@".simple-work-node {
    margin: 5px;
    text-align: center;
}");
            sbHtml.Append(@".countersign-work-node {
    padding: 5px;
    border-style: solid;
    border-width: 1px;
    border-color: #40e0d069;
    margin: 5px;
    border-radius: 8px;
    text-align: center;
    background-color: #40e0d069;
}");
            sbHtml.Append(@".countersign-work-node .child {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    border-style: solid;
    border-width: 1px;
    border-color: #016e71;
    border-radius: 5px;
    margin: 5px;
}");
            sbHtml.Append(@".paralle-work-node {
    padding: 5px;
    border-style: solid;
    border-width: 1px;
    border-color: #5f9ea087;
    margin: 5px;
    border-radius: 8px;
    text-align: center;
    background-color: #5f9ea087;
}");
            sbHtml.Append(@".paralle-work-node .child {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    border-style: solid;
    border-width: 1px;
    border-color: #016e71;
    border-radius: 5px;
    margin: 5px;
}");

            sbHtml.Append(@".child-item {
    border-style: solid;
    border-width: 0px;
    border-radius: 5px;
    margin: 0px;
    display: flex;
    align-items: center;
    flex-wrap: nowrap;
    align-content: center;
    justify-content: center;
}");

            sbHtml.Append("</style>");
            sbHtml.Append("</head>");
            sbHtml.Append("<body>");
            sbHtml.Append("<div class='nodeView'>");

            var sn1 = repository.SimpleWorkNodes.FirstOrDefault(p => p.Name.Equals("简单节点1"));
            sn1.RenderToHtml(sbHtml);

            var sb = new StringBuilder();

            sb.Append("</div>");
            sb.Append("</body>");
            sb.Append("</html>");

            await LogAsync(sbHtml.ToString());

            //foreach (var node in repository.SimpleWorkNodes.OrderBy(p=>p.Name).ToList())
            //{
            //    await LogSimpleWorkNode(node);
            //}

            //foreach(var node in repository.CountersignNodes.OrderBy(p => p.Name).ToList())
            //{
            //    await LogCountersignNode(node);
            //}
            //foreach (var node in repository.ParalleNodes.OrderBy(p => p.Name).ToList())
            //{
            //    await LogParalleNode(node);
            //}
        }

        private async Task LogCountersignNode(CountersignNode countersignNode)
        {
            await LogContentAsync($"会签节点【{countersignNode.Name}】，下个节点：{GetNextWorkNode(countersignNode)}");
            foreach (var node in countersignNode.ChildNodes)
            {
                await LogContentAsync($"会签节点【{countersignNode.Name}】，子节点【{node.Name}】");
                if (node is CountersignNode)
                {
                    await LogCountersignNode(node as CountersignNode);
                }
                else if (node is SimpleWorkNode)
                {
                    await LogSimpleWorkNode(node as SimpleWorkNode);
                }
                else if (node is ParalleNode)
                {
                    await LogParalleNode(node as ParalleNode);
                }
            }
        }

        private async Task LogParalleNode(ParalleNode paralleNode)
        {
            await LogContentAsync($"并行节点【{paralleNode.Name}】，下个节点：{GetNextWorkNode(paralleNode)}");
            foreach (var node in paralleNode.ChildNodes)
            {
                await LogContentAsync($"并行节点【{paralleNode.Name}】，子节点【{node.Name}】");
                if (node is CountersignNode)
                {
                    await LogCountersignNode(node as CountersignNode);
                }
                else if (node is SimpleWorkNode)
                {
                    await LogSimpleWorkNode(node as SimpleWorkNode);
                }
                else if (node is ParalleNode)
                {
                    await LogParalleNode(node as ParalleNode);
                }
            }

        }

        private async Task LogSimpleWorkNode(SimpleWorkNode simpleWorkNode)
        {
            await LogContentAsync($"简单节点【{simpleWorkNode.Name}】，下个节点：{GetNextWorkNode(simpleWorkNode)}");
        }

        private string GetNextWorkNode(WorkNode workNode)
        {
            var sb = new StringBuilder();
            var nextNode = workNode.NextNode;
            while (nextNode != null)
            {
                sb.Append($" =>【{nextNode.Name}】");
                nextNode = nextNode.NextNode;
            }
            return sb.ToString();
        }
        private async Task LogTitleAsync(string message)
        {
            await LogAsync($@"<h2>{message}</h2>");
        }
        private async Task LogContentAsync(string message)
        {
            await LogAsync($@"<div><span>{message}</span></div>");
        }

        private async Task LogAsync(string message)
        {
            await _context.Response.WriteAsync(message, new UTF8Encoding(false));
        }
    }
}
